import type { AppointmentManagement } from '@shared/types/'
import type { IHttpSession } from '../request/http-session'
import type { ProxySelectionResult } from '../request/proxy-utils'
import type { BookingOptions, BookingOutcome, BookingStrategy } from './strategy'
import { getConfig } from '../config/index'
import { createContextLogger } from '../logger/index'
import { HttpSession } from '../request/http-session'
import { HttpSessionV2 } from '../request/http-session-v2'
import { selectProxyForRequestSession } from '../request/proxy-utils'
import { TdabsFlows } from '../request/tdabs-flows'
import { getPageParser } from '../shared/page-parser'
import { ProxyLease } from '../shared/proxy-lease'
import { isGlobalCancelRequested } from './engine-registry'

export class RequestBookingStrategy implements BookingStrategy {
  /**
   * 预约操作
   *
   * @description 香港运输署网站开始预约流程：E 操作
   * 流程：startOperation('E') → enterEntry('E') → getApptInfoByIdentity → 日历 → 时段 → 确认 → 提交
   *
   * @param {AppointmentManagement} appointment - 预约记录
   * @param {BookingOptions} options - 预约选项
   * @returns {Promise<BookingOutcome>} 预约结果
   */
  async book(appointment: AppointmentManagement, options?: BookingOptions): Promise<BookingOutcome> {
    // 若全局已请求停止，立即短路
    if (isGlobalCancelRequested())
      return { success: false, error: '预约已被停止' }

    // 为每个预约选择代理
    const config = getConfig()
    const proxyEnabled = !!config?.proxy?.enabled
    const disableProxy = (options as any)?.disableProxy === true
    let proxy: ProxySelectionResult | null = null
    if (proxyEnabled && !disableProxy) {
      proxy = selectProxyForRequestSession()
    }

    // 记录代理选择日志（包含代理池信息）
    const logger = createContextLogger({ component: 'RequestBookingStrategy' })
    if (proxyEnabled) {
      try {
        // 获取代理黑名单
        const blacklist = Array.isArray(config?.proxy?.temp_blacklist) ? config.proxy.temp_blacklist : []
        // 获取当前有效的代理黑名单数量
        const blacklistActive = blacklist.filter((b: any) => b && (!b.until || b.until > Date.now())).length

        if (proxy) {
          logger.info('🧩 Request 模式代理选择', {
            enabled: proxyEnabled,
            blacklist_active: blacklistActive,
            picked: {
              server: proxy.server,
              hasAuth: !!proxy.username,
            },
            provider: {
              id: proxy.providerId || 'unknown',
              label: proxy.providerLabel || 'unknown',
            },
            pool_stats: {
              total_candidates: proxy.candidateSize || 0,
              after_blacklist_filter: proxy.filteredSize || 0,
              total_pool_size: proxy.poolSize || 0,
            },
          })
        }
        else {
          logger.info('🧩 Request 模式代理选择', {
            enabled: proxyEnabled,
            blacklist_active: blacklistActive,
            picked: null,
            reason: '未找到可用代理',
          })
        }
      }
      catch {}
    }

    // 转换为 HttpSession 需要的格式
    const proxyForSession = proxy
      ? {
          server: proxy.server,
          username: proxy.username,
          password: proxy.password,
        }
      : undefined

    // 根据配置/环境变量选择使用原生HttpSession还是高性能HttpSessionV2
    // 优先环境变量快速开关：FORCE_ORIGINAL_HTTP=1 或 NETWORK_USE_UNDICI=0 → 原生
    const envForceOriginal = String((process as any)?.env?.FORCE_ORIGINAL_HTTP || '').trim() === '1'
      || String((process as any)?.env?.NETWORK_USE_UNDICI || '').trim() === '0'
    const useUndici = !envForceOriginal && (config.network?.use_undici !== false) // 默认启用undici
    const session: IHttpSession = useUndici
      ? new HttpSessionV2(undefined, proxyForSession)
      : new HttpSession(undefined, proxyForSession)

    // 传递预约数据信息用于HTML分类存储
    const appointmentMetadata = {
      appointmentId: appointment.id,
      passportNumber: appointment.passport_number,
      licenseNumber: appointment.license_number,
      fullName: appointment.full_name,
      sequenceNumber: appointment.sequence_number,
    }
    const flows = new TdabsFlows(session, appointmentMetadata)
    const parser = getPageParser()

    // 解析首选日期：优先 options.preferredDates，其次 appointment.preferred_dates
    const parsePreferredFromAppointment = (): string[] => {
      try {
        const raw: any = appointment?.preferred_dates
        if (!raw)
          return []
        if (Array.isArray(raw))
          return raw.filter(Boolean).map(String)
        const s = String(raw)
        // JSON 数组或逗号/分号/空格分隔
        if (s.trim().startsWith('[')) {
          try {
            const arr = JSON.parse(s)
            return Array.isArray(arr) ? arr.filter(Boolean).map(String) : []
          }
          catch {
            /* fallthrough */
          }
        }
        return s.split(/[;,\s]+/).map(t => t.trim()).filter(Boolean)
      }
      catch {
        return []
      }
    }

    const preferredDates = Array.isArray(options?.preferredDates) && options!.preferredDates.length > 0
      ? options!.preferredDates
      : parsePreferredFromAppointment()

    if (isGlobalCancelRequested())
      return { success: false, error: '预约已被停止' }

    // 获取预约办公地点
    const office = options?.officeCode || appointment.office_code || 'HKLO'
    // 执行预约操作
    let result: any
    try {
      result = await flows.bookNewFromIdentity(
        {
          passport: appointment.passport_number,
          license: appointment.license_number,
        },
        {
          officeCode: office,
          preferredDates,
          preferredTimes: options?.preferredTimes || [],
          forcePreferredDates: appointment.force_preferred_dates || false,
          allowedDateRange: options?.allowedDateRange,
          // 传递用户信息用于身份验证
          licenseOwnerName: appointment.full_name,
          email: appointment.email,
          phone: appointment.phone_number,
          issuingCountry: appointment.issuing_country || 'CN',
          issuingAuthority: appointment.issuing_authority || 'GD',
          // 传递 jobId 和 onProgress 用于UI日志
          jobId: options?.jobId,
          onProgress: options?.onProgress,
        } as any,
      )
    }
    finally {
      try {
        if (proxy && proxy.leased && proxy.server)
          ProxyLease.release(proxy.server)
      }
      catch {}
    }

    if (result.success) {
      // 尝试从结果页解析参考号
      const brief = parser.parseBookingResult(result.html)
      // 优先使用result中返回的实际选择的日期和时间，如果没有则使用首选项
      const actualDate = (result as any)?.selectedDate || options?.preferredDates?.[0]
      const actualTimeslot = (result as any)?.selectedTimeslot || options?.preferredTimes?.[0]
      return {
        success: true,
        referenceNumber: (brief.success && brief.data?.success) ? brief.data.reference_number : result.reference,
        selectedDate: actualDate, // 使用实际选择的日期
        selectedTimeslot: actualTimeslot, // 使用实际选择的时段
      }
    }
    return { success: false, error: result.error || 'submit failed' }
  }
}
